package com.swak.fx.support.ui;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;

/**
 * 一行
 * 
 * @author 618lf
 */
public class UICell extends GridPane implements UILifecycle {

	private final String STYLE_CLASS = "ui-cell";
	private final String TEXT_STYLE_CLASS = "ui-cell_text";
	private final String VALUE_STYLE_CLASS = "ui-cell_value";
	private final String OPS_STYLE_CLASS = "ui-cell_ops";
	private final String STYLESHEET = UI.load("css/UICell.css");

	public UICell() {
		this.init();
	}

	@Override
	public void initializeParts() {
		getStyleClass().add(STYLE_CLASS);
	}

	@Override
	public void setupValueChangedListeners() {
		textNodeProperty().addListener((ob, o, n) -> this.onTextNodeChange(o, n));
		valueNodeProperty().addListener((ob, o, n) -> this.onValueNodeChange(o, n));
		opsNodeProperty().addListener((ob, o, n) -> this.onOpsNodeChange(o, n));
	}

	private void onTextNodeChange(Node old, Node add) {
		if (old != null) {
			this.getChildren().remove(old);
		}
		if (add != null) {
			this.getChildren().add(add);
			add.getStyleClass().add(TEXT_STYLE_CLASS);
			GridPane.setConstraints(add, 0, 0);
			GridPane.setHgrow(add, Priority.NEVER);
			GridPane.setVgrow(add, Priority.ALWAYS);
			GridPane.setHalignment(add, HPos.CENTER);
			GridPane.setValignment(add, VPos.CENTER);
			GridPane.setMargin(add, new Insets(0, 10, 0, 0));
		}
	}

	private void onValueNodeChange(Node old, Node add) {
		if (old != null) {
			this.getChildren().remove(old);
		}
		if (add != null) {
			this.getChildren().add(add);
			add.getStyleClass().add(VALUE_STYLE_CLASS);
			GridPane.setConstraints(add, 1, 0);
			GridPane.setHgrow(add, Priority.ALWAYS);
			GridPane.setVgrow(add, Priority.ALWAYS);
			GridPane.setHalignment(add, HPos.LEFT);
			GridPane.setValignment(add, VPos.CENTER);
		}
	}

	private void onOpsNodeChange(Node old, Node add) {
		if (old != null) {
			this.getChildren().remove(old);
		}
		if (add != null) {
			this.getChildren().add(add);
			add.getStyleClass().add(OPS_STYLE_CLASS);
			GridPane.setConstraints(add, 2, 0);
			GridPane.setHgrow(add, Priority.NEVER);
			GridPane.setVgrow(add, Priority.ALWAYS);
			GridPane.setHalignment(add, HPos.CENTER);
			GridPane.setValignment(add, VPos.CENTER);
			GridPane.setMargin(add, new Insets(0, 0, 0, 10));
		}
	}

	// ================================================================================
	// Overridden Methods
	// ================================================================================
	@Override
	public String getUserAgentStylesheet() {
		return STYLESHEET;
	}

	// ================================================================================
	// Properties
	// ================================================================================

	private final ObjectProperty<Node> textNodeProperty = new SimpleObjectProperty<Node>(this, "text-node");
	private final ObjectProperty<Node> valueNodeProperty = new SimpleObjectProperty<Node>(this, "value-node");
	private final ObjectProperty<Node> opsNodeProperty = new SimpleObjectProperty<Node>(this, "ops-node");

	public ObjectProperty<Node> textNodeProperty() {
		return textNodeProperty;
	}

	public ObjectProperty<Node> valueNodeProperty() {
		return valueNodeProperty;
	}

	public ObjectProperty<Node> opsNodeProperty() {
		return opsNodeProperty;
	}
}